#include "common_game.h"
#include "game.h"
#include "logic.h"
#include "main.h"
#include "network.h"
#include "generator/dungeon.h"
#include "generator/graph.h"
#include "util/mt.h"

static void spawn_characters ();

void common_game_init ()
{
	memset (the_game.player, 0, sizeof(the_game.player));
	the_game.n_players = 0;
	
	spawn_characters ();
	logic_reset ();
}

// Creates a map, maybe?
void common_game_seed (unsigned long seed, int n_characters)
{
	assert((n_characters > 0) && (n_characters < MAX_PLAYERS));
	
	tile_init ();
	
	Graph g;
	graph_init (&g, n_characters, NUM_DUNGEON_SEGMENTS);
	graph_generate (&g, n_characters, the_game.seed);
	dungeon_generate (&g, &the_game.map, MAP_WIDTH, MAP_HEIGHT);
	graph_cleanup (&g);
	
	the_game.seed = seed;
	the_game.game_time = 0;
}

void common_game_cleanup ()
{
	map_cleanup (&the_game.map);
	for (int i = 0; i < the_game.map.actor.count; i++) {
		actor_cleanup (map_get_actor (&the_game.map, i));
	}
	tile_cleanup ();
}

/*
 * Spawns exactly as many characters as there are spawn points on 
 * the map. If the amount of available spawn points is too low or
 * too high for the number of players who actually want to play,
 * an error will be raised elsewhere sooner or later.
 */
static void spawn_characters ()
{
	if (the_game.map.n_spawns == 0) return;
	
	int n_spawns = the_game.map.n_spawns;
	
	assert((n_spawns > 0) && (n_spawns <= MAX_SPAWNPOINTS));
	assert(the_game.map.actor.count == 0); // must have virgin game obj
	
	for (int i = 0; i < n_spawns; i++) {
		Coord coord = the_game.map.spawn[i];
		actor_alloc_character (map_get_actor (&the_game.map, i), i, coord, PLAYER_HPINIT,
		                       the_network.player[i].character_type + 1);
		                       
		Tile* tile = &TILEC (&the_game.map, coord);
		tile->actor = i;
		tile->has_actor = true;
		
		#if TOWERHACK_DEBUG
		int item = mt_randint (WEAPONS_CLOSE_BEGIN, WEAPONS_CLOSE_END);
		map_get_actor (&the_game.map, i)->character->inventory.slot[items[item].type - ITEM_WEAPON_CLOSE] = item;
		#endif
	}
	
	the_game.map.actor.count = n_spawns;
}
